package com.cs.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cs.constant.ProdConstant;
import com.cs.domain.Prod;
import com.cs.domain.ProdComm;
import com.cs.domain.ProdTagReference;
import com.cs.domain.Sku;
import com.cs.mapper.ProdCommMapper;
import com.cs.mapper.ProdMapper;
import com.cs.mapper.ProdTagReferenceMapper;
import com.cs.service.ProdService;
import com.cs.service.ProdTagReferenceService;
import com.cs.service.SkuService;
import com.netflix.discovery.converters.Auto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ProdServiceImpl extends ServiceImpl<ProdMapper, Prod> implements ProdService {

    @Autowired
    private ProdMapper prodMapper;
    @Autowired
    private SkuService skuService;

    @Autowired
    private ProdTagReferenceMapper prodTagReferenceMapper;
    @Autowired
    private ProdTagReferenceService prodTagReferenceService;
    @Autowired
    private ProdCommMapper prodCommMapper;

    /**
     * 分页查询商品的接口
     *
     * @param page
     * @param prod
     * @return
     */
    @Override
    public Page<Prod> findProdPage(Page<Prod> page, Prod prod) {
        page.addOrder(OrderItem.desc("create_time"));
        Page<Prod> prodPage = prodMapper.selectPage(page, new LambdaQueryWrapper<Prod>().eq(!ObjectUtils.isEmpty(prod.getStatus()), Prod::getStatus, prod.getStatus())
                .like(!StringUtils.isEmpty(prod.getProdName()), Prod::getProdName, prod.getProdName()));
        return prodPage;
    }

    /**
     * 查询总条数
     *
     * @param o
     * @param o1
     * @return
     */
    @Override
    public Integer getTotal(Date o, Date o1) {
        Integer integer = prodMapper.selectCount(new LambdaQueryWrapper<Prod>().between((!ObjectUtils.isEmpty(o) && !ObjectUtils.isEmpty(o1)), Prod::getUpdateTime, o, o1));
        return integer;
    }

    /**
     * 上架产品
     *
     * @param prod
     * @return
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean save(Prod prod) {
        log.info("上架商品{}" + JSON.toJSONString(prod));
        prod.setUpdateTime(new Date());
        prod.setCreateTime(new Date());
        if (prod.getStatus() == 1) {
            prod.setPutawayTime(new Date());
        }
        prod.setVersion(0);
        prod.setShopId(1L);
        //拿到配送的方式
        Prod.DeliveryModeVo deliveryModeVo = prod.getDeliveryModeVo();
        String deliveryMode = JSON.toJSONString(deliveryModeVo);
        // 放到prod的配送属性里面去
        prod.setDeliveryMode(deliveryMode);
        int insert = prodMapper.insert(prod);
        if (insert > 0) {
            // 处理sku
            handlerSku(prod.getSkuList(), prod.getProdId());
            // 处理标签分组
            this.handlerTagReference(prod.getTagList(), prod.getProdId());

        }
        return insert > 0;
    }

    /**
     * 处理标签分组的关系表
     * 商品与分组标签是多对多的关系
     * 所有需要一个中间表
     *
     * @param tagList
     * @param prodId
     */
    private void handlerTagReference(List<Long> tagList, Long prodId) {
        if (CollectionUtils.isEmpty(tagList)) {
            return;
        }
        ArrayList<ProdTagReference> prodTagReferences = new ArrayList<>(tagList.size() * 2);
        // 循环标签分组id的集合
        tagList.forEach(tagId -> {
            ProdTagReference prodTagReference = new ProdTagReference();
            prodTagReference.setShopId(1L);
            prodTagReference.setCreateTime(new Date());
            prodTagReference.setTagId(tagId);
            prodTagReference.setProdId(prodId);
            prodTagReference.setStatus(true);
            prodTagReferences.add(prodTagReference);
        });
        // 操作数据库
        prodTagReferenceService.saveBatch(prodTagReferences);
    }

    /**
     * 处理sku
     *
     * @param skuList
     * @param prodId
     */
    private void handlerSku(List<Sku> skuList, Long prodId) {
        if (CollectionUtils.isEmpty(skuList)) {
            return;
        }
        // 循环sku集合 设置prodId
        skuList.forEach(sku -> {
            sku.setProdId(prodId);
            sku.setVersion(0);
            sku.setRecTime(new Date());
            sku.setUpdateTime(new Date());
            sku.setActualStocks(sku.getStocks());
            sku.setIsDelete(0);
        });
        // 操作插入sku
        skuService.saveBatch(skuList);
    }

    /**
     * 根据时间区分页查询商品的对象
     *
     * @param page
     * @param t1
     * @param t2
     * @return
     */
    @Override
    public List<Prod> findProdPageByTime(Page<Prod> page, Object t1, Object t2) {
        Page<Prod> prodPage = prodMapper.selectPage(page, new LambdaQueryWrapper<Prod>().between(t1 != null && t2 != null, Prod::getUpdateTime, t1, t2));
        //获得商品的数据
        List<Prod> prodList = prodPage.getRecords();
        if(CollectionUtils.isEmpty(prodList)){
            return Collections.emptyList();
        }
        //商品的和标签是多对多的关系 有一个中间表 来查询商品的标签
        //获得商品的ids
        List<Long> prodIds = prodList.stream().map(Prod::getProdId).collect(Collectors.toList());
        // 查询tag_reference
        List<ProdTagReference> prodTagReferences = prodTagReferenceMapper.selectList(new LambdaQueryWrapper<ProdTagReference>().in(ProdTagReference::getProdId, prodIds));
        if(!CollectionUtils.isEmpty(prodTagReferences)){
            //每个商品的对象都需要标签的集合
            prodList.forEach(prod -> {
                List<Long> tagList = prodTagReferences.stream().filter(prodTagReference -> prodTagReference.getProdId().equals(prod.getProdId())).
                        map(ProdTagReference::getTagId).collect(Collectors.toList());
                prod.setTagList(tagList);
            });
        }
        //评论
        List<ProdComm> prodCommList = prodCommMapper.selectList(new LambdaQueryWrapper<ProdComm>().in(ProdComm::getProdId, prodIds));
        prodList.forEach(prod -> {

            Boolean flag = true;
            //获得商品的评论
            List<ProdComm> prodComms = prodCommList.stream().filter(prodComm -> prodComm.getProdId().equals(prod.getProdId())).collect(Collectors.toList());
            if(!CollectionUtils.isEmpty(prodComms)){
                //拿到商品的总评
                int totalComm = prodComms.size();
                //商品的好评
                long goodsComm = prodComms.stream().filter(prodComm -> prodComm.getEvaluate().equals(0)).count();
                if(goodsComm!=0){
                    flag = false;
                    BigDecimal goodsLv = new BigDecimal(goodsComm)
                            .divide(new BigDecimal(totalComm),2,BigDecimal.ROUND_HALF_UP)
                            .multiply(new BigDecimal(100));
                   //设置商品的好评率
                    prod.setPositiveRating(goodsLv);
                    //设置商品的好评数
                    prod.setPraiseNumber((long) goodsComm);
                }

            }
            if(flag){
                prod.setPraiseNumber(0L);
                prod.setPositiveRating(BigDecimal.ZERO);
            }

        });
        return prodList;
    }
}
